"""
Configuration management for EndoSight-UC AI Inference Server V3.0
Centralized settings with environment variable support
"""

import os
from typing import List, Optional
from pydantic import BaseSettings, validator
import structlog


class Settings(BaseSettings):
    """Application settings with validation and environment variable support"""

    # [修复 H2] CORS 配置: 严禁使用 "*"
    # 示例: "http://localhost:3000,https://prod-domain.com"
    ALLOWED_ORIGINS: List[str] = ["http://localhost:3000", "http://localhost:8101"]

    # [修复 H1] 模型路径: 从环境变量读取
    MODEL_PATH: str = "uc_model/final_weights/uceis_best_model.pth"

    # [修复 L7] 日志级别
    LOG_LEVEL: str = "INFO"

    # [修复 M4] 速率限制配置 (示例: 每分钟 20 次)
    RATE_LIMIT_PER_MINUTE: int = 20

    # 输入安全配置
    MAX_FILE_SIZE_MB: int = 10
    ALLOWED_MIME_TYPES: List[str] = ["image/jpeg", "image/png", "image/bmp"]

    # Server configuration
    HOST: str = "0.0.0.0"
    PORT: int = 5001

    # Security configuration
    API_KEY: Optional[str] = None
    SECRET_KEY: str = "dev-secret-key-change-in-production-v4"

    # V4.0 Enhanced security settings
    ENABLE_SECURITY_HEADERS: bool = True
    ENABLE_REQUEST_LOGGING: bool = True
    MAX_CONCURRENT_REQUESTS: int = 100
    SESSION_TIMEOUT_MINUTES: int = 30
    ENABLE_AI_SECURITY_CHECKS: bool = True

    # Performance configuration
    MAX_WORKERS: int = 4
    WORKER_TIMEOUT: int = 30

    # Monitoring and health
    HEALTH_CHECK_INTERVAL: int = 60

    @validator('ALLOWED_ORIGINS', pre=True)
    def parse_origins(cls, v):
        """Parse comma-separated origins string into list"""
        if isinstance(v, str):
            return [origin.strip() for origin in v.split(',')]
        return v

    @validator('ALLOWED_MIME_TYPES', pre=True)
    def parse_mime_types(cls, v):
        """Parse comma-separated mime types string into list"""
        if isinstance(v, str):
            return [mime.strip() for mime in v.split(',')]
        return v

    @validator('RATE_LIMIT_PER_MINUTE')
    def validate_rate_limit(cls, v):
        """Ensure rate limit is reasonable"""
        if v < 1 or v > 1000:
            raise ValueError('Rate limit must be between 1 and 1000 requests per minute')
        return v

    @validator('MAX_FILE_SIZE_MB')
    def validate_max_file_size(cls, v):
        """Ensure max file size is reasonable"""
        if v < 1 or v > 100:
            raise ValueError('Max file size must be between 1 and 100 MB')
        return v

    @validator('LOG_LEVEL')
    def validate_log_level(cls, v):
        """Ensure log level is valid"""
        valid_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
        if v.upper() not in valid_levels:
            raise ValueError(f'Log level must be one of: {valid_levels}')
        return v.upper()

    @validator('SECRET_KEY')
    def validate_secret_key(cls, v):
        """V4.0: Enhanced secret key validation"""
        # Check environment context
        is_prod = os.getenv('ENVIRONMENT', 'development').lower() == 'production'

        if is_prod:
            # Production validation
            if v in [
                "your-secret-key-change-in-production",
                "dev-secret-key-change-in-production-v4",
                "your-secret-key-change-in-production-please"
            ]:
                raise ValueError('SECRET_KEY must be changed in production!')

            if len(v) < 64:
                raise ValueError('SECRET_KEY must be at least 64 characters in production!')

            # Check for entropy (basic)
            unique_chars = len(set(v))
            if unique_chars < len(v) * 0.6:  # At least 60% unique characters
                raise ValueError('SECRET_KEY has low entropy, use more random characters')

        else:
            # Development validation (more lenient)
            if len(v) < 32:
                raise ValueError('SECRET_KEY must be at least 32 characters long')

        # Check for common weak patterns
        weak_patterns = [
            'password', 'secret', 'key', '123', 'admin', 'test',
            'demo', 'example', 'sample', 'default', 'changeme'
        ]
        v_lower = v.lower()
        if any(pattern in v_lower for pattern in weak_patterns):
            raise ValueError('SECRET_KEY contains common weak patterns')

        return v

    @validator('MODEL_PATH')
    def validate_model_path(cls, v):
        """V4.0: Validate model path for security"""
        # Prevent path traversal attacks
        if '..' in v or v.startswith('/') or v.startswith('\\'):
            raise ValueError('MODEL_PATH must be relative to project root')

        # Ensure it's a .pth file
        if not v.endswith('.pth'):
            raise ValueError('MODEL_PATH must point to a .pth file')

        return v

    @validator('ALLOWED_ORIGINS')
    def validate_cors_origins(cls, v):
        """V4.0: Validate CORS origins for security"""
        for origin in v:
            # Prevent wildcard in production
            if origin == '*':
                is_prod = os.getenv('ENVIRONMENT', 'development').lower() == 'production'
                if is_prod:
                    raise ValueError('Wildcard CORS origin "*" not allowed in production')

            # Validate URL format
            if not origin.startswith(('http://', 'https://')):
                raise ValueError(f'Invalid CORS origin format: {origin}')

        return v

    class Config:
        # 允许从 .env 文件加载
        env_file = ".env"
        env_file_encoding = 'utf-8'
        case_sensitive = True

    def get_cors_origins(self) -> List[str]:
        """Get CORS origins with fallback to localhost for development"""
        return self.ALLOWED_ORIGINS if self.ALLOWED_ORIGINS else ["http://localhost:3000"]

    def is_production(self) -> bool:
        """Check if running in production environment"""
        return os.getenv('ENVIRONMENT', 'development').lower() == 'production'

    def get_model_path(self) -> str:
        """Get absolute model path"""
        if not os.path.isabs(self.MODEL_PATH):
            # Relative to project root
            return os.path.join(os.path.dirname(__file__), '..', '..', self.MODEL_PATH)
        return self.MODEL_PATH


# Global settings instance
settings = Settings()


# V4.0 Enhanced configuration validation
def validate_config():
    """V4.0: Comprehensive configuration validation"""
    logger = structlog.get_logger()

    try:
        # 1. Model file validation
        model_path = settings.get_model_path()
        if not os.path.exists(model_path):
            raise FileNotFoundError(f"Model file not found at: {model_path}")

        # 2. Production security checks
        if settings.is_production():
            logger.info("Running production security validation")

            # Enhanced secret key validation
            forbidden_keys = [
                "your-secret-key-change-in-production",
                "dev-secret-key-change-in-production-v4",
                "your-secret-key-change-in-production-please"
            ]
            if settings.SECRET_KEY in forbidden_keys:
                raise ValueError("SECRET_KEY must be changed in production!")

            # Check CORS origins
            if '*' in settings.ALLOWED_ORIGINS:
                raise ValueError("Wildcard CORS origin not allowed in production!")

            # Check rate limits
            if settings.RATE_LIMIT_PER_MINUTE > 1000:
                raise ValueError("Rate limit too high for production")

            # Check file size limits
            if settings.MAX_FILE_SIZE_MB > 50:
                raise ValueError("File size limit too high for production")

        # 3. Security feature validation
        if not settings.ENABLE_SECURITY_HEADERS:
            logger.warning("Security headers are disabled")

        if not settings.ENABLE_AI_SECURITY_CHECKS:
            logger.warning("AI security checks are disabled")

        # 4. Resource limits validation
        if settings.MAX_CONCURRENT_REQUESTS > 1000:
            raise ValueError("Concurrent request limit too high")

        if settings.WORKER_TIMEOUT > 300:
            raise ValueError("Worker timeout too high")

        # 5. Model path security validation
        normalized_path = os.path.normpath(settings.MODEL_PATH)
        if normalized_path.startswith('..') or os.path.isabs(normalized_path):
            raise ValueError("Model path must be relative and within project directory")

        logger.info("Configuration validation passed",
                   production=settings.is_production(),
                   model_path=model_path,
                   cors_origins=len(settings.ALLOWED_ORIGINS))

        return True

    except Exception as e:
        logger.error("Configuration validation failed", error=str(e))
        raise


if __name__ == "__main__":
    # Test configuration
    try:
        validate_config()
        print("✅ Configuration validation passed")
        print(f"Model path: {settings.get_model_path()}")
        print(f"CORS origins: {settings.get_cors_origins()}")
        print(f"Rate limit: {settings.RATE_LIMIT_PER_MINUTE}/minute")
        print(f"Max file size: {settings.MAX_FILE_SIZE_MB}MB")
    except Exception as e:
        print(f"❌ Configuration validation failed: {e}")